package com.cskaoyan.wordmemorize.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cskaoyan.wordmemorize.common.constant.ResultCodeEnum;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLog;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLogConstant;
import com.cskaoyan.wordmemorize.common.exception.BusinessException;
import com.cskaoyan.wordmemorize.converter.GoodsConverter;
import com.cskaoyan.wordmemorize.dao.entity.GoodsDO;
import com.cskaoyan.wordmemorize.dao.mapper.GoodsMapper;
import com.cskaoyan.wordmemorize.dto.admin.DeleteGoodsOperateDTO;
import com.cskaoyan.wordmemorize.dto.admin.GoodsDTO;
import com.cskaoyan.wordmemorize.dto.admin.PageDTO;
import com.cskaoyan.wordmemorize.request.BatchDeleteCommand;
import com.cskaoyan.wordmemorize.request.GoodsCommand;
import com.cskaoyan.wordmemorize.request.GoodsPageRequest;
import com.cskaoyan.wordmemorize.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

// todo 【后台管理-商品相关功能】
@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    GoodsMapper goodsMapper;

    @Autowired
    GoodsConverter goodsConverter;

    // todo 获取商品的分页列表
    @Override
    public PageDTO<GoodsDTO> getGoodsPage(GoodsPageRequest request) {

        // todo 没给任何参数, 全表查询
        if(request.getPageNum() == null){
            LambdaQueryWrapper<GoodsDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            List<GoodsDO> goodsDOS = goodsMapper.selectList(lambdaQueryWrapper);
            return goodsConverter.goodsPage2PageDTO(goodsDOS, (long)goodsDOS.size());
        }

        // todo 分页查询
        Page<GoodsDO> goodsDOPage = new Page<>(request.getPageNum(), request.getCount());
        LambdaQueryWrapper<GoodsDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // todo 检查是否给于关键字参数, 如果有还需加上模糊查询的条件
        if(request.getKeyword() != null){
            lambdaQueryWrapper.like(GoodsDO::getName, request.getKeyword());
        }
        Page<GoodsDO> goodsDOPage1 = goodsMapper.selectPage(goodsDOPage, lambdaQueryWrapper);
        return goodsConverter.goodsPage2PageDTO(goodsDOPage1.getRecords(), goodsDOPage1.getTotal());
    }

    // todo 【移动端】获取所有商品数据
    @Override
    public PageDTO<GoodsDTO> getAllGoods(GoodsPageRequest request) {

        if(request.getPageNum() == null){
            LambdaQueryWrapper<GoodsDO> wrapper = new LambdaQueryWrapper<>();
            if(request.getTypes() != null){
                wrapper.in(GoodsDO::getType, request.getTypes());
            }
            wrapper.eq(GoodsDO::getStatus, 1);
            List<GoodsDO> goodsDOS = goodsMapper.selectList(wrapper);
            return goodsConverter.goodsPage2PageDTO(goodsDOS, (long)goodsDOS.size());
        }

        Page<GoodsDO> goodsDOPage = new Page<>(request.getPageNum(), request.getCount());
        LambdaQueryWrapper<GoodsDO> wrapper2 =  new LambdaQueryWrapper<>();
        if(request.getTypes() != null){
            wrapper2.in(GoodsDO::getType, request.getTypes());
        }
        wrapper2.eq(GoodsDO::getStatus, 1);
        Page<GoodsDO> goodsDOPage1 = goodsMapper.selectPage(goodsDOPage, wrapper2);
        return goodsConverter.goodsPage2PageDTO(goodsDOPage1.getRecords(), goodsDOPage1.getTotal());
    }

    // todo 添加商品
    @OperateLog(dataType = "商品", operateType = OperateLogConstant.OPERATE_ADD)
    @Override
    public void addGoods(GoodsCommand command) {

        // todo 判断商品是否已经存在 根据商品名
        LambdaQueryWrapper<GoodsDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(GoodsDO::getName, command.getName());

        GoodsDO goodsDO = goodsMapper.selectOne(lambdaQueryWrapper);
        if(goodsDO != null){
            throw new BusinessException(ResultCodeEnum.GOODS_EXIST);
        }

        // todo 保存商品
        GoodsDO insertGoodsDO = goodsConverter.command2GoodsDO(command);
        goodsMapper.insert(insertGoodsDO);

    }

    // todo 修改商品
    @OperateLog(dataType = "商品", operateType = OperateLogConstant.OPERATE_UPDATE)
    @Override
    public void updateGoods(GoodsCommand command) {

        // todo 判断商品是否存在
        LambdaQueryWrapper<GoodsDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(GoodsDO::getId, command.getId());
        GoodsDO goodsDO = goodsMapper.selectOne(lambdaQueryWrapper);
        if(goodsDO == null){
            throw new BusinessException(ResultCodeEnum.GOODS_NOT_EXIST);
        }

        // todo 执行到这步就说明存在, 开始更改
        GoodsDO updateGoodsDO = goodsConverter.command2GoodsDO(command);
        goodsMapper.update(updateGoodsDO, lambdaQueryWrapper);
    }

    // todo 删除商品
    @OperateLog(dataType = "商品", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    @Override
    public DeleteGoodsOperateDTO deleteGoods(Long goodsId) {
        // todo 判断商品是否存在
        LambdaQueryWrapper<GoodsDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(GoodsDO::getId, goodsId);
        GoodsDO goodsDO = goodsMapper.selectOne(lambdaQueryWrapper);
        if(goodsDO == null){
            throw new BusinessException(ResultCodeEnum.GOODS_NOT_EXIST);
        }

        // todo 执行到这步就说明存在, 开始逻辑删除, 删除完后将查询的结果返回
        LambdaUpdateWrapper<GoodsDO> goodsDOLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        goodsDOLambdaUpdateWrapper.eq(GoodsDO::getId, goodsId)
                .set(GoodsDO::getIsDeleted, 1);
        goodsMapper.update(null, goodsDOLambdaUpdateWrapper);

        return goodsConverter.goodsDO2DeleteGoodsDTO(goodsDO);

    }

    // todo 删除选中商品
    @OperateLog(dataType = "商品", operateType = OperateLogConstant.OPERATE_BATCH_DELETE)
    @Override
    public List<DeleteGoodsOperateDTO> deleteGoodsSelected(BatchDeleteCommand command) {
        // todo 判断选中的商品是否都存在
        for(String id : command.getIds()){
            LambdaQueryWrapper<GoodsDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(GoodsDO::getId, Long.valueOf(id));
            GoodsDO goodsDO = goodsMapper.selectOne(lambdaQueryWrapper);
            if(goodsDO == null){
                throw new BusinessException(ResultCodeEnum.GOODS_NOT_EXIST);
            }
        }

        // todo 如果都存在, 进行批量删除
        List<DeleteGoodsOperateDTO> deleteGoodsDTOS = new ArrayList<>();
        for(String id : command.getIds()){
            DeleteGoodsOperateDTO deleteGoodsOperateDTO = this.deleteGoods(Long.valueOf(id));
            deleteGoodsDTOS.add(deleteGoodsOperateDTO);
        }
        return deleteGoodsDTOS;
    }

    // todo 修改商品状态
    @OperateLog(dataType = "商品", operateType = OperateLogConstant.OPERATE_UPDATE_STATUS)
    @Override
    public void updateGoodsStatus(Long goodsId, Integer status) {

        // todo 判断商品是否存在
        LambdaQueryWrapper<GoodsDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(GoodsDO::getId, goodsId);
        GoodsDO goodsDO = goodsMapper.selectOne(lambdaQueryWrapper);
        if(goodsDO == null){
            throw new BusinessException(ResultCodeEnum.GOODS_NOT_EXIST);
        }

        // todo 执行到这步就说明存在, 开始更改
        LambdaUpdateWrapper<GoodsDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(GoodsDO::getId, goodsId)
                .set(GoodsDO::getStatus, status);
        goodsMapper.update(null, lambdaUpdateWrapper);
    }
}
